package me.zhengjie.kwService.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.kwService.ExamTeacherService;
import me.zhengjie.kwService.MasterTearcherService;
import me.zhengjie.mapper.*;
import me.zhengjie.pojo.dto.ExamTeacherAddReplaceDto;
import me.zhengjie.pojo.dto.SaveExamTeacherDto;
import me.zhengjie.pojo.entity.*;
import me.zhengjie.pojo.export.ExamTeacherExport;
import me.zhengjie.util.AssertUtils;
import me.zhengjie.util.BaseResponse;
import me.zhengjie.util.ruoyiexcel.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @author Long
 * @date 2021/6/28 17:02
 */
@Service
public class ExamTeacherServiceImpl extends ServiceImpl<ExamTeacherMapper, ExamTeacher> implements ExamTeacherService {
    @Autowired
    private ExamTeacherMapper examTeacherMapper;
    @Autowired
    private ExamRoomMapper examRoomMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private MasterTearcherService masterTearcherService;
    @Autowired
    private MasterTearcherMapper masterTearcherMapper;
    @Autowired
    private OccupyMapper occupyMapper;
    @Autowired
    private ExamMapper examMapper;

    @Override
    public List<ExamTeacher> selectList() {
        return examTeacherMapper.selectList(null);
    }

    @Override
    public Page<ExamTeacher> findAllExamTeacher(Integer pageNo, Integer pageSize) {
        Page<ExamTeacher> page = new Page<>(pageNo, pageSize);
        return examTeacherMapper.selectPage(page, null);
    }

    @Override
    public BaseResponse export(HttpServletResponse response, List<ExamTeacher> examTeachers) {
        /**如果选中了数据导出，那么查询出对应的考场id的考场名和对应的部门id的部门名称添加到导出模板中导出*/
        LinkedList<ExamTeacherExport> examTeacherExports = new LinkedList<>();
        if (examTeachers.size() != 0 && examTeachers != null) {
            for (ExamTeacher examTeacher : examTeachers) {
                ExamTeacherExport examTeacherExport = new ExamTeacherExport();
                BeanUtils.copyProperties(examTeacher, examTeacherExport);
                if (examTeacher.getExamRoomId() != null) {
                    ExamRoom examRoom = examRoomMapper.selectById(examTeacher.getExamRoomId());
                    if (examRoom != null && StringUtils.isNotBlank(examRoom.getNameCn())) {
                        examTeacherExport.setExamRoomNameCn(examRoom.getNameCn());
                    }
                }
                if (examTeacher.getDeptId() != null) {
                    Dept dept = deptMapper.selectById(examTeacher.getDeptId());
                    if (StringUtils.isNotBlank(dept.getName())) {
                        examTeacherExport.setName(dept.getName());
                    }
                }
                examTeacherExports.add(examTeacherExport);
            }
        } else {
            /**如果没选中数据导出，那么默认导出全部数据*/
            List<ExamTeacher> list = examTeacherMapper.selectList(null);
            for (ExamTeacher examTeacher : list) {
                ExamTeacherExport examTeacherExport = new ExamTeacherExport();
                BeanUtils.copyProperties(examTeacher, examTeacherExport);
                if (examTeacher.getExamRoomId() != null) {
                    ExamRoom examRoom = examRoomMapper.selectById(examTeacher.getExamRoomId());
                    examTeacherExport.setExamRoomNameCn(examRoom.getNameCn());
                }
                if (examTeacher.getDeptId() != null) {
                    Dept dept = deptMapper.selectById(examTeacher.getDeptId());
                    if (StringUtils.isNotBlank(dept.getName())) {
                        examTeacherExport.setName(dept.getName());
                    }
                }
                examTeacherExports.add(examTeacherExport);
            }
        }
        if (examTeacherExports.size() > 0) {
            ExcelUtil<ExamTeacherExport> excelUtil = new ExcelUtil<>(ExamTeacherExport.class);
            try {
                /*excelUtil.exportExcel(examTeacherExports, "监考教师安排信息");*/
                excelUtil.exportExcel(response, examTeacherExports, "监考教师安排信息");
                return BaseResponse.ok("导出成功");
            } catch (Exception e) {
                e.printStackTrace();
                return BaseResponse.failed("导出失败：" + e.getMessage());
            }
        }
        return BaseResponse.ok("无数据可导出");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveImportList(List<ExamTeacherExport> examTeacherExports, Integer examId) {
        AssertUtils.isNotNull(examId, "考试id不可为空");
        LinkedList<ExamTeacher> examTeacherList = new LinkedList<>();
        LinkedList<MasterTearcher> masterTearcherList = new LinkedList<>();
        for (ExamTeacherExport teacherExport : examTeacherExports) {
            /*校验参数不可为空*/
            AssertUtils.isNotNull(teacherExport.getIdCard(), "身份证、姓名、手机号必填");
            AssertUtils.isNotNull(teacherExport.getNameCn(), "身份证、姓名、手机号必填");
            AssertUtils.isNotNull(teacherExport.getPhone(), "身份证、姓名、手机号必填");
            AssertUtils.isMobile(teacherExport.getPhone(),teacherExport.getNameCn()+"的手机号格式不正确");
            AssertUtils.isIdCard(teacherExport.getIdCard(),teacherExport.getNameCn()+"的身份证号格式不正确");
            if(Objects.equals(teacherExport.getType(),"0")){
                AssertUtils.isNotNull(teacherExport.getJobNumber(), "类型为上报的监考人员工号不能为空");
            }
            if (teacherExport.getSex() == null) teacherExport.setSex(0);

            ExamTeacher examTeacher = new ExamTeacher();
            BeanUtils.copyProperties(teacherExport, examTeacher);
            examTeacher.setExamId(examId);
            /*根据导入的考场名，查询考场表对应的id存入*/
            if (StringUtils.isNotBlank(teacherExport.getExamRoomNameCn())) {
                QueryWrapper<ExamRoom> examRoomWrapper = new QueryWrapper<>();
                examRoomWrapper.eq("name_cn", teacherExport.getExamRoomNameCn());
                ExamRoom examRoom = examRoomMapper.selectOne(examRoomWrapper);
                AssertUtils.isNotNull(examRoom, "不存在这个考场：" + teacherExport.getExamRoomNameCn());
                if (examRoom.getId() != null) {
                    examTeacher.setExamRoomId(examRoom.getId());
                }
            }
            /*根据传入的部门名称，查询对应的id存入*/
            if (StringUtils.isNotBlank(teacherExport.getName())) {
                QueryWrapper<Dept> deptWrapper = new QueryWrapper<>();
                deptWrapper.eq("name", teacherExport.getName());
                Dept dept = deptMapper.selectOne(deptWrapper);
                if (dept != null && dept.getDeptId() != null) {
                    examTeacher.setDeptId(dept.getDeptId());
                }
            }
            /*根据教师身份证查询，如果没有则插入教师表，返回主键存入监考教师表*/
            if (StringUtils.isNotBlank(teacherExport.getIdCard())) {
                QueryWrapper<MasterTearcher> masterTearcherWrapper = new QueryWrapper<>();
                masterTearcherWrapper.eq("id_card", teacherExport.getIdCard());
                MasterTearcher tearcher = masterTearcherMapper.selectOne(masterTearcherWrapper);
                if (tearcher == null) {
                    MasterTearcher masterTearcher = new MasterTearcher();
                    BeanUtils.copyProperties(teacherExport, masterTearcher);
                    masterTearcherMapper.insert(masterTearcher);
                    examTeacher.setTeacherId(masterTearcher.getId());
                } else {
                    examTeacher.setTeacherId(tearcher.getId());
                }
            }
            QueryWrapper<ExamTeacher> wrapper = new QueryWrapper<>();
            wrapper.eq("id_card", examTeacher.getIdCard())
                    .eq("exam_id", examId);
            this.saveOrUpdate(examTeacher, wrapper);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse saveExamTeacher(SaveExamTeacherDto dto) {
        QueryWrapper<Occupy> wrapper = new QueryWrapper<>();
        wrapper.eq("type_id", dto.getTeacherId())
                .eq("type", "1");
        List<Occupy> list = occupyMapper.selectList(wrapper);
        long examStartTime = dto.getStartTime().getTime();
        long examEndTime = dto.getEndTime().getTime();
        if (!list.isEmpty()) {
            for (Occupy o : list) {
                long endTime = o.getEndTime().getTime();
                long startTime = o.getStartTime().getTime();
                /*如果传入的考试开始时间在表中的开始时间和结束时间之中则说明考试被占用*/
                if (examStartTime >= startTime && examStartTime <= endTime) {
                    return BaseResponse.failed("本次考试的开始时间在该教师的一场考试之间");
                }
                if (examEndTime >= startTime && examEndTime <= endTime) {
                    return BaseResponse.failed("本次考试的结束时间在该教师的一场考试之间");
                }
                if (startTime >= examStartTime && startTime <= examEndTime) {
                    return BaseResponse.failed("该教师有一场考试的开始时间在本次考试时间段之间");
                }
                if (endTime >= examStartTime && endTime <= examEndTime) {
                    return BaseResponse.failed("该教师有一场考试的结束时间在本次考试时间段之间");
                }
            }
        }
        /*如选择的教师身份不包含选中的身份类型,则对其添加对应的身份类型*/
        MasterTearcher masterTearcher = masterTearcherMapper.selectById(dto.getTeacherId());
        if (!masterTearcher.getIdentity().contains(dto.getIdentity())) {
            masterTearcher.setIdentity(masterTearcher.getIdentity() + dto.getIdentity());
            masterTearcherMapper.updateById(masterTearcher);
        }
        /*保存监考教师安排信息*/
        ExamTeacher examTeacher = new ExamTeacher();
        BeanUtils.copyProperties(dto, examTeacher);
        examTeacher.setCreateTime(new Date())
                .setUpdateTime(new Date());
        save(examTeacher);

        /*考务人员不记录占用信息*/
        if ("1".equals(dto.getIdentity())) return BaseResponse.ok("新增成功");
        /*保存该监考教师的监考时间，考试id等信息*/
        Occupy occupy = new Occupy();
        BeanUtils.copyProperties(dto, occupy);
        occupy.setUpdateTime(new Date())
                .setCreateTime(new Date())
                .setType("1")
                .setTypeId(dto.getTeacherId());
        occupyMapper.insert(occupy);
        return BaseResponse.ok("新增成功");
    }

    /**
     * 给监考老师安排替补老师
     *
     * @param dto 教师安排id、替补教师id
     * @return
     */
    @Override
    public BaseResponse addReplaceTeacher(ExamTeacherAddReplaceDto dto) {
        ExamTeacher examTeacher = examTeacherMapper.selectById(dto.getId());
        if (dto.getReplaceTeacherId() == null) {
            examTeacher.setTeacherId(null);
            examTeacherMapper.updateById(examTeacher);
            return BaseResponse.ok();
        }
        QueryWrapper<Occupy> wrapper = new QueryWrapper<>();
        wrapper.eq("type", "1")
                .eq("type_id", dto.getReplaceTeacherId());
        List<Occupy> list = occupyMapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            Exam exam = examMapper.selectById(examTeacher.getExamId());
            long examStartTime = exam.getStartTime().getTime();
            long examEndTime = exam.getEndTime().getTime();
            for (Occupy o : list) {
                long endTime = o.getEndTime().getTime();
                long startTime = o.getStartTime().getTime();
                /*如果传入的考试开始时间在表中的开始时间和结束时间之中则说明考试被占用*/
                if (examStartTime >= startTime && examStartTime <= endTime) {
                    return BaseResponse.failed("本次考试的开始时间在该替补教师的一场考试之间");
                }
                if (examEndTime >= startTime && examEndTime <= endTime) {
                    return BaseResponse.failed("本次考试的结束时间在该替补教师的一场考试之间");
                }
                if (startTime >= examStartTime && startTime <= examEndTime) {
                    return BaseResponse.failed("该替补教师有一场考试的开始时间在本次考试时间段之间");
                }
                if (endTime >= examStartTime && endTime <= examEndTime) {
                    return BaseResponse.failed("该替补教师有一场考试的结束时间在本次考试时间段之间");
                }
            }
        }
        examTeacher.setReplaceTeacherId(dto.getReplaceTeacherId());
        examTeacherMapper.updateById(examTeacher);
        return BaseResponse.ok();
    }
}
